package com.voltbarn.vbsensors;

import java.util.List;

import uk.co.jasonfry.android.tools.ui.PageControl;
import uk.co.jasonfry.android.tools.ui.SwipeView;
import uk.co.jasonfry.android.tools.ui.SwipeView.OnPageChangedListener;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.view.KeyEvent;



public class StationSwipe extends Activity {

	private List<Message> messages;
	private Handler sHandler = new Handler();
	private int curPage = 1;
	private int numStations = 0;
	private String[] station = {"", "vbsensorpack", "vbsensorpack", "vbsensorpack","vbsensorpack", "vbsensorpack", "vbsensorpack", "vbsensorpack", "vbsensorpack"};
	private String[] myType = {"", "vbsp", "vbsp", "vbsp", "vbsp", "vbsp", "vbsp", "vbsp", "vbsp"};
	private float[]pTemp = {0,0,0,0,0,0,0,0};
	private float[]pWinds = {0,0,0,0,0,0,0,0};
	private float[]pRain = {0,0,0,0,0,0,0,0};
	private float[]pRain24 = {0,0,0,0,0,0,0,0};
	private float[]pHumid = {0,0,0,0,0,0,0,0};
	private float[]pPress = {0,0,0,0,0,0,0,0};
	private long[]uTime = {System.currentTimeMillis(),
			System.currentTimeMillis(),
			System.currentTimeMillis(),
			System.currentTimeMillis(),
			System.currentTimeMillis(),
			System.currentTimeMillis(),
			System.currentTimeMillis(),
			System.currentTimeMillis(),
			};

	SwipeView mSwipeView;

	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.station);
		
		initData();
		updateUIx();
		
		sHandler.postDelayed(updateData, 15000); // Do first auto update in 15 seconds
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
	    if ((keyCode == KeyEvent.KEYCODE_BACK)) {
	    	this.finish();
	        return true;
	    }
	    return super.onKeyDown(keyCode, event);
	}
	
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		// Comment out to ignore, landscape rules in this view 
		//setContentView(R.layout.station);		
		//updateUIx();
		// Old update, doesn't work updateUInew(curPage);
	}
	
	private void initData() {
		loadStationDB();
		messages = grabData(0); // Initialize things
		for (int i = 0; i < numStations; i++) {
			if (i != 0) {
				messages.addAll(grabData(i));
			}
		}
		int i = 0;
		for (Message m: messages) {
			resetPrev(m, i);
		}
	}
	
	private void resetPrev(Message m, int i) {
	
			try {
				pTemp[i] = Float.valueOf(m.getTemperature()).floatValue();
			} catch (NullPointerException e) {			
			} catch (NumberFormatException e) {				
			}	
			
			try {
				pHumid[i] = Float.valueOf(m.getHumidity()).floatValue();
			} catch (NullPointerException e) {			
			} catch (NumberFormatException e) {				
			}
			
			try {
				pPress[i] = Float.valueOf(m.getPressure()).floatValue();
			} catch (NullPointerException e) {			
			} catch (NumberFormatException e) {				
			}
			
			try {
				pWinds[i] = Float.valueOf(m.getWinds()).floatValue();
			} catch (NullPointerException e) {			
			} catch (NumberFormatException e) {				
			}
			
			try {
				pRain[i] = Float.valueOf(m.getRain()).floatValue();
			} catch (NullPointerException e) {			
			} catch (NumberFormatException e) {				
			}
			
			try {
				pRain24[i] = Float.valueOf(m.getRain24()).floatValue();
			} catch (NullPointerException e) {			
			} catch (NumberFormatException e) {				
			}	
			i++;
	}
	
	
	private int intToImage(char numberChar) {
		// By trying base 11 here, we allow an "a" value to show a decimal point
		// if the temp is over 100, i.e. 100.
		int numberInt = Character.digit(numberChar, 11);
		int images[] = { R.drawable.zero, R.drawable.one, R.drawable.two,
				R.drawable.three, R.drawable.four, R.drawable.five,
				R.drawable.six, R.drawable.seven, R.drawable.eight,
				R.drawable.nine,R.drawable.dot }; // srcId
		if (numberInt < 0 || numberInt > 10) {
			return images[10];
		} else {
			return  images[numberInt];
		}
	}
	
	private void updateUIx() {
		/* Define wrapper controls */
		PageControl mPageControl = (PageControl) findViewById(R.id.page_control);
		mSwipeView = (SwipeView) findViewById(R.id.swipe_view);
		
		for (int i = 0; i < numStations; i++) {
			updateUInew(i);
		}
		
		/* Set up listeners and stuff */
		SwipeTextLoader mSwipeTextLoader = new SwipeTextLoader();
		mSwipeView.setOnPageChangedListener(mSwipeTextLoader);
		mSwipeView.setPageControl(mPageControl);
	}

	private void updateUInew(int page) {
		String stemp;
		
		if (page >= numStations) {
			Log.e("updateUInew", "Page > numStations" + Integer.toString(page) + ">" + Integer.toString(numStations));
			return;
		}
		if (page >= messages.size()) {
			Log.e("updateUInew", "Page > numStations" + Integer.toString(page) + ">" + Integer.toString(messages.size()));
			return;
		}
		if (page == 0) {
			Log.e("updateUInew", "Page is Zero");
		}
		/* Define wrapper controls */
		mSwipeView = (SwipeView) findViewById(R.id.swipe_view);
		
		/* Clear out anything there now */
		LinearLayout xll = ((LinearLayout) mSwipeView.getChildContainer().getChildAt(page));
		if (xll != null)
		  ((LinearLayout) mSwipeView.getChildContainer().getChildAt(page)).removeAllViews();
		/*
		else
		  ((LinearLayout) mSwipeView.getChildContainer()).removeAllViews();
		  */
		
		mSwipeView.addView(new LinearLayout(this));
		LinearLayout ll = ((LinearLayout)mSwipeView.getChildContainer().getChildAt(page));
		if (ll == null) {
			Log.e("updateUInew", "ll == null. Gack.");
			return;
		}
		ll.setOrientation(LinearLayout.VERTICAL);
		ll.setBackgroundColor(Color.GRAY);
		
		/* Do full layout of all the child widgets for this screen */

		String ps;
		String ps2;
		addField(ll, page, R.dimen.textSizeStation, false,
				" StationID: ", messages.get(page).getID(), "",
				R.drawable.blank, "");
		
		ps = Float.toString(pTemp[page]);
		addField(ll, page, R.dimen.textSizeStationLarge, true,
				" Temperature: ", messages.get(page).getTemperature(), "F", 
				whatArrow(messages.get(page).getTemperature(), pTemp, page), ps);
		
		ps = Float.toString(pWinds[page]);
		addField(ll, page, R.dimen.textSizeStationLarge, true,
				" WindSpeed: ", messages.get(page).getWinds(), "mph", 
				whatArrow(messages.get(page).getWinds(), pWinds, page), ps);
		
		ps = Float.toString(pRain[page]);
		ps2 = Float.toString(pRain24[page]);
		addFieldTwo(ll, page, R.dimen.textSizeStationMed, true,
				" Rain: " , messages.get(page).getRain() , "in", 
				whatArrow(messages.get(page).getRain(), pRain, page), ps,
				" Rain24: " , messages.get(page).getRain24() , "", 
				whatArrow(messages.get(page).getRain24(), pRain24, page), ps2);
		
		ps = Float.toString(pHumid[page]);
		ps2 = Float.toString(pPress[page]);
		addFieldTwo(ll, page, R.dimen.textSizeStation, false,
				" Humidity: " , messages.get(page).getHumidity() , "%", 
				whatArrow(messages.get(page).getHumidity(), pHumid, page), ps,
				" Pressure: " , messages.get(page).getPressure() , "inHg", 
				whatArrow(messages.get(page).getPressure(), pPress, page), ps2);
		
		addField(ll, page, R.dimen.textSizeStation, false, " ",
				messages.get(page).getDates(), "", R.drawable.blank, "");
	}
	
	private int whatArrow(String vs, float[] fa, int page) {
		int postImage = R.drawable.blank;

		float f;
		
		Log.e("whatArrow", "Checking new value " + vs + " against old value of " + Float.toString(fa[page]));
		try {
			f = Float.valueOf(vs).floatValue();
		} catch (NullPointerException e) {
			return R.drawable.blank;
		} catch (NumberFormatException e) {
			return R.drawable.blank;
		}
		if (f == fa[page])
			postImage = R.drawable.blank;
		else if (f > fa[page])
			postImage = R.drawable.arrowupgreen;
		else
			postImage = R.drawable.arrowdownred;
		//fa[page] = f;
		// Timeout didn't seem to help with trends. Think harder 
		if ((uTime[page] + 600000) < System.currentTimeMillis()) {
			Log.e("whatArrow", "In timeout, resetting old value to new");
			// reset all the old values
			resetPrev(messages.get(page), page);
			uTime[page] = System.currentTimeMillis();
		}
		
		return postImage;
	}
	
	/* A really, really icky, lazy hack. Wanted Rain and Rain24 to be next to each other, so created this to build that one line, copying from
	 * addField. Will have to reflect any changes to addField into this identical routine. Did this, since we're building out the layout
	 * programatically, and I wasn't sure how to get an individual LinearLayout I'd added, after adding it.
	 */
	
	private void addFieldTwo(LinearLayout ll, int page, int size,  boolean large,
			String prefix1, String str1, String suffix1, int postimage1, String prev1,
			String prefix2, String str2, String suffix2, int postimage2, String prev2) {
		
		LinearLayout ll2 = new LinearLayout(this);
		ll2.setOrientation(LinearLayout.HORIZONTAL);
		ll2.setVerticalGravity(Gravity.CENTER);
		ll.addView(ll2);
		
		if (str1 != null) {
		  TextView tv = new TextView(this);
		  tv.setTextSize(this.getResources().getDimension(size));
		  tv.setTextColor(Color.BLACK);
		  tv.setTypeface(Typeface.SERIF, Typeface.BOLD);
		  tv.setText(prefix1 + str1 + (str1.equals("N/A") ? "" : suffix1));
		  ll2.addView(tv);
		}
		
		ImageView iv;
		
		int aheight = (large ? 60 : 40);
		int awidth = (large ? 80 : 60);
	    iv = new ImageView(this);		
		iv.setAdjustViewBounds(true);
		iv.setMaxHeight(aheight);
		iv.setMaxWidth(awidth);
		iv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
				
		iv.setImageResource(postimage1);
		ll2.addView(iv);
		
		if (str1 != null && prev1 != "" && postimage1 != R.drawable.blank) {
				TextView tv = new TextView(this);
				tv.setTextSize(this.getResources().getDimension(size));
				tv.setTextColor(Color.BLACK);
				tv.setTypeface(Typeface.SERIF, Typeface.NORMAL);
				tv.setText("(" + prev1 + ")");
				ll2.addView(tv);
		}
		
		if (str2 != null) {
			  TextView tv = new TextView(this);
			  tv.setTextSize(this.getResources().getDimension(size));
			  tv.setTextColor(Color.BLACK);
			  tv.setTypeface(Typeface.SERIF, Typeface.BOLD);
			  tv.setText(prefix2 + str2 + (str2.equals("N/A") ? "" : suffix2));
			  ll2.addView(tv);
			}
		
	    iv = new ImageView(this);		
		iv.setAdjustViewBounds(true);
		iv.setMaxHeight(aheight);
		iv.setMaxWidth(awidth);
		iv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
				
		iv.setImageResource(postimage2);
		ll2.addView(iv);
		
		if (str2 != null && prev2 != "" && postimage2 != R.drawable.blank) {
				TextView tv = new TextView(this);
				tv.setTextSize(this.getResources().getDimension(size));
				tv.setTextColor(Color.BLACK);
				tv.setTypeface(Typeface.SERIF, Typeface.NORMAL);
				tv.setText("(" + prev2 + ")");
				ll2.addView(tv);
		}
	}
	
	private void addField(LinearLayout ll, int page, int size, boolean large, String prefix, String str, String suffix, int postimage, String prev) {
	LinearLayout ll2 = new LinearLayout(this);
	ll2.setOrientation(LinearLayout.HORIZONTAL);
	ll2.setVerticalGravity(Gravity.CENTER);
	ll.addView(ll2);
	
	if (str != null) {
	  TextView tv = new TextView(this);
	  tv.setTextSize(this.getResources().getDimension(size));
	  tv.setTextColor(Color.BLACK);
	  tv.setTypeface(Typeface.SERIF, Typeface.BOLD);
	  tv.setText(prefix + str + (str.equals("N/A") ? "" : suffix));
	  ll2.addView(tv);
	}
	
	int aheight = (large ? 60 : 40);
	int awidth = (large ? 80 : 60);
	ImageView iv = new ImageView(this);		
	iv.setAdjustViewBounds(true);
	iv.setMaxHeight(aheight);
	iv.setMaxWidth(awidth);
	iv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
			
	iv.setImageResource(postimage);
	ll2.addView(iv);

	if (str != null && prev != "" && postimage != R.drawable.blank) {
			TextView tv = new TextView(this);
			tv.setTextSize(this.getResources().getDimension(size));
			tv.setTextColor(Color.BLACK);
			tv.setTypeface(Typeface.SERIF, Typeface.NORMAL);
			tv.setText("(" + prev + ")");
			ll2.addView(tv);
	}
	}
	
	
	private void updateUI() {

		PageControl mPageControl = (PageControl) findViewById(R.id.page_control);
		mSwipeView = (SwipeView) findViewById(R.id.swipe_view);

		for (int i = 0; i < numStations; i++) {
			mSwipeView.addView(new LinearLayout(this));
			LinearLayout ll = ((LinearLayout)mSwipeView.getChildContainer().getChildAt(i));
			/*
			 * Do full layout of all the child widgets for this screen
			ImageView iv1 = new ImageView(this);
			iv1.setImageResource(R.drawable.one);
			ll.addView(iv1);
			ImageView iv2 = new ImageView(this);
			iv2.setImageResource(R.drawable.two);
			ll.addView(iv2);
			*/
			TextView tx = new TextView(this);
			weatherText(tx, i);
			ll.addView(tx);
		}
		SwipeTextLoader mSwipeTextLoader = new SwipeTextLoader();
		mSwipeView.setOnPageChangedListener(mSwipeTextLoader);
		mSwipeView.setPageControl(mPageControl);
	}

	private void weatherText(TextView t, int i) {
		t.setTypeface(Typeface.SERIF, Typeface.BOLD);
		t.setTextSize(this.getResources().getDimension(R.dimen.textSizeStation));
		//t.setTextSize(48);
		t.setTextColor(R.string.textBlue2);
		t.setText("StationID: " + messages.get(i).getID() + "\n\n"); 
		t.append("\n Temperature: " + messages.get(i).getTemperature() + "F\n");
		t.append("\n Humidity: " + messages.get(i).getHumidity() + "\n");
		t.append("\n Pressure: " + messages.get(i).getPressure() + "inHg\n");
		String ws = messages.get(i).getWinds();
		if (ws != null)
			t.append("\n Wind Speed: " + ws + "\n");
		String r = messages.get(i).getRain();
		if (r != null)
			t.append("\n Rainfall: " + r + "\n");
		String rd = messages.get(i).getRain24();
		if (rd != null)
			t.append("\n Rainfall(24hr): " + rd + "\n");
		//t.setBackgroundResource(R.drawable.fewcloudsday);
		t.append("\n Date: " + messages.get(i).getDates());

	}

	private Runnable updateData = new Runnable() {
		public void run() {
			int cp = mSwipeView.getCurrentPage();
			//new updateInBG();
			try {
				messages.set(cp, grabData(cp).get(0));
				updateUInew(cp);
			} catch (IndexOutOfBoundsException e) {
			  // Don't know why these sometimes happen, but let's handle it anyway
			}  
			/*
			((LinearLayout) mSwipeView.getChildContainer().getChildAt(cp)).removeAllViews();
			TextView t = new TextView(StationSwipe.this);
			weatherText(t, cp);
			((LinearLayout) mSwipeView.getChildContainer().getChildAt(cp)).addView(t);
			*/
			sHandler.postDelayed(updateData, 60000); // Do auto update in 1 minute
		}
	};

	private class updateInBG extends AsyncTask {
		protected Object doInBackground(Object... arg0) {
			messages.set(curPage, grabData(curPage).get(0));
			updateUI();
			return null;
		}
	}

	private void grabCachedData(int forPage) {

	}

	private void loadStationDB() {
		Cursor cursor = null;
		VbDBAdapter mDbHelper = new VbDBAdapter(getBaseContext());


		mDbHelper.openRO();
		if (mDbHelper.getNumEntries() != 0) {
			cursor = mDbHelper.fetchAllSensors();
		}
		if (cursor == null)
			return;

		int id = cursor.getCount();
		int i;
		int stationCount;
		numStations = id;
		cursor.moveToFirst();
		for (i = 0, stationCount = 0; i < id; i++, cursor.moveToNext()) {	
			station[i] = cursor.getString(1);
			myType[i] = cursor.getString(2);
		}
		mDbHelper.close();
	}

	private List<Message> grabData(int forPage) {

		Context context = getApplicationContext();

		BaseFeedParser parser;
		
		/* Set the prior data before we get the new data, if there is any
		int iii = forPage;
		
		if (messages != null) 
		if (forPage < messages.size()) {
			long ttime = uTime[forPage] + 120000;
			long ntime = System.currentTimeMillis();

			int i = forPage;
			Log.e("GrabData", "GrabData for page " + String.valueOf(forPage));
			try {
				float f = Float.valueOf(messages.get(i).getTemperature()).floatValue();
				pTemp[i]   = Float.valueOf(messages.get(i).getTemperature()).floatValue();
			} catch (NullPointerException e) {			
			} catch (NumberFormatException e) {				
			}
			try {
				pHumid[i]  = Float.valueOf(messages.get(i).getHumidity()).floatValue();
			} catch (NullPointerException e) {			
			} catch (NumberFormatException e) {				
			}		
			try {
				pPress[i]  = Float.valueOf(messages.get(i).getPressure()).floatValue();
			} catch (NullPointerException e) {			
			} catch (NumberFormatException e) {				
			}
			try {
				pWinds[i]  = Float.valueOf(messages.get(i).getWinds()).floatValue();
			} catch (NullPointerException e) {			
			} catch (NumberFormatException e) {				
			}	
			try {
				pRain[i]   = Float.valueOf(messages.get(i).getRain()).floatValue();
			} catch (NullPointerException e) {			
			} catch (NumberFormatException e) {				
			}
			try {
				pRain24[i] = Float.valueOf(messages.get(i).getRain24()).floatValue();
			} catch (NullPointerException e) {			
			} catch (NumberFormatException e) {				
			}
		}
	*/
		if (myType[forPage].equals("vbsp") ) { // Need to handle WU too
			parser = new BaseFeedParser(getString(R.string.sensorURL) + station[forPage] + ".xml");
		} else { // We'll assume it's WU
			parser = new BaseFeedParser(getString(R.string.wuURL) + station[forPage]);
		}
		List<Message> mess = parser.parse();

		if (mess.size() == 0) {	
			// Voltbarn web service will return an error, so parse will return null
			//Toast.makeText(context, "VB Station not found: " + station, durationl).show();					
		} else if (mess.get(0).getID() == "") {
			// WeatherUnderground will return a full reply, with everything in it zeroed
			// Toast.makeText(context, "WU Station not found: " + station, durationl).show();					
		} else {

		}
		return mess;
	}


	private class SwipeTextLoader implements OnPageChangedListener
	{

		public void onPageChanged(int oldPage, int newPage) 
		{
			curPage = newPage;
			if(newPage>oldPage)//going forwards
			{
				//if(newPage != (mSwipeView.getPageCount()-1))//if at the end, don't load one page after the end
				if(newPage != (numStations-1))//if at the end, don't load one page after the end

				{
					int foo = mSwipeView.getPageCount();
					updateUInew(newPage+1);
					/*
					TextView t = new TextView(StationSwipe.this);
					weatherText(t, newPage+1);
					((LinearLayout) mSwipeView.getChildContainer().getChildAt(newPage+1)).addView(t);
					*/
				}
				if(oldPage !=0 ) //if at the beginning, don't destroy one before the beginning
				{
					((LinearLayout) mSwipeView.getChildContainer().getChildAt(oldPage-1)).removeAllViews();
				}

			}
			else //going backwards
			{
				if(newPage != 0) //if at the beginning, don't load one before the beginning
				{
					updateUInew(newPage-1);
					/*
					TextView t = new TextView(StationSwipe.this);
					weatherText(t, newPage-1);
					((LinearLayout) mSwipeView.getChildContainer().getChildAt(newPage-1)).addView(t);
					*/
				}
				if(oldPage != (mSwipeView.getPageCount()-1))//if at the end, don't destroy one page after the end
				{
					((LinearLayout) mSwipeView.getChildContainer().getChildAt(oldPage+1)).removeAllViews();
				}
			}
		}
	}
}


